package pers.bc.utils.file;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;

/**
 * Java文件编码转换工具 - 将指定目录中的所有Java文件转换为UTF-8编码
 */
public class JavaFileToUTF8Converter
{
    
    // 统计信息
    private static int totalFiles = 0;
    private static int convertedFiles = 0;
    private static int failedFiles = 0;
    private static List<String> failedFileList = new ArrayList<>();
    
    public static void main(String[] args)
    {
     
        String directoryPath = "D:\\workspace\\workspaceLBC\\yyappclog\\baseapp\\clog\\src";
        File directory = new File(directoryPath);
        
        if (!directory.exists() || !directory.isDirectory())
        {
            System.out.println("错误: 指定的路径不存在或不是一个目录: " + directoryPath);
            return;
        }
        
        System.out.println("开始扫描目录: " + directoryPath);
        System.out.println("正在查找Java文件并转换为UTF-8编码...\n");
        
        try
        {
            processDirectory(directory);
            
            // 输出统计信息
            System.out.println("\n转换完成!");
            System.out.println("总Java文件数: " + totalFiles);
            System.out.println("成功转换: " + convertedFiles);
            System.out.println("失败: " + failedFiles);
            
            if (failedFiles > 0)
            {
                System.out.println("\n失败的文件列表:");
                for (String filePath : failedFileList)
                {
                    System.out.println("  - " + filePath);
                }
            }
            
        }
        catch (IOException e)
        {
            System.out.println("处理过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 递归处理目录中的所有Java文件
     */
    private static void processDirectory(File directory) throws IOException
    {
        // 使用Files.walkFileTree递归遍历目录
        Files.walkFileTree(directory.toPath(), new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
            {
                if (file.toString().toLowerCase().endsWith(".java"))
                {
                    totalFiles++;
                    try
                    {
                        if (convertToUTF8(file.toFile()))
                        {
                            convertedFiles++;
                            System.out.println("成功转换: " + file);
                        }
                    }
                    catch (IOException e)
                    {
                        failedFiles++;
                        failedFileList.add(file.toString());
                        System.err.println("转换文件失败: " + file + " - " + e.getMessage());
                    }
                }
                return FileVisitResult.CONTINUE;
            }
            
            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc)
            {
                System.err.println("无法访问文件: " + file + " - " + exc.getMessage());
                return FileVisitResult.CONTINUE;
            }
        });
    }
    
    /**
     * 将单个Java文件转换为UTF-8编码
     */
    private static boolean convertToUTF8(File file) throws IOException
    {
        // 检测当前文件编码
        Charset detectedCharset = detectCharset(file);
          detectedCharset = Charset.forName("GB2312");

        // 如果已经是UTF-8编码，则跳过
        if (detectedCharset.equals(StandardCharsets.UTF_8))
        {
            System.out.println("跳过(已是UTF-8): " + file.getAbsolutePath());
            return false;
        }
        
        System.out.println("转换: " + file.getAbsolutePath() + " (" + detectedCharset.displayName() + " -> UTF-8)");
        
        // 读取文件内容
        String content;
        try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), detectedCharset))
        {
            StringBuilder sb = new StringBuilder();
            char[] buffer = new char[1024];
            int read;
            while ((read = reader.read(buffer)) != -1)
            {
                sb.append(buffer, 0, read);
            }
            content = sb.toString();
        }
        
        // 以UTF-8编码写入文件
        try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))
        {
            writer.write(content);
        }
        
        return true;
    }
    
    /**
     * 检测文件的编码格式
     */
    private static Charset detectCharset(File file) throws IOException
    {
        // 尝试常见的编码格式
        Charset[] candidates = {
            StandardCharsets.UTF_8,
            Charset.forName("GBK"),
            Charset.forName("GB2312"),
            StandardCharsets.ISO_8859_1,
            StandardCharsets.US_ASCII,
            Charset.forName("Windows-1252"),
            Charset.forName("ISO-8859-2")};
        
        for (Charset charset : candidates)
        {
            if (isCharset(file, charset))
            {
                return charset;
            }
        }
        
        // 如果无法确定编码，默认使用系统默认编码
        System.out.println("警告: 无法确定文件编码，使用系统默认编码: " + file.getAbsolutePath());
        return Charset.defaultCharset();
    }
    
    /**
     * 检查文件是否使用指定的编码格式
     */
    private static boolean isCharset(File file, Charset charset)
    {
        try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), charset))
        {
            // 尝试读取文件内容，如果没有异常，则可能是正确的编码
            char[] buffer = new char[1024];
            while (reader.read(buffer) != -1)
            {
                // 只是尝试读取，不处理内容
            }
            return true;
        }
        catch (Exception e)
        {
            // 读取时出现异常，可能不是正确的编码
            return false;
        }
    }
}
